<!DOCTYPE html>
<html>
<head>
    <title>Cylinder Electric Field Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            background-color: #ffffff;
            border: 1px solid #d3d3d3;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="600" height="350"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // --- Style and Font Definitions ---
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        const baseLineWidth = 2;
        const thinLineWidth = 1;
        const mainFont = 'italic 22px "Times New Roman"';
        const captionFont = '22px "KaiTi", "SimSun"';

        // --- Geometric Parameters ---
        const yc = 120;      // y-coordinate of the central axis
        const l = 250;       // Pixel length of the cylinder
        const R = 55;        // Pixel radius of the cylinder
        const d = 100;       // Pixel distance from cylinder to point P
        const ellipseRx = 20; // x-radius of the end ellipses for perspective

        const x_left_center = 120;
        const x_right_center = x_left_center + l;
        const x_p = x_right_center + d;

        // --- Drawing Functions ---

        function drawArrow(x1, y1, x2, y2) {
            const headlen = 8;
            const angle = Math.atan2(y2 - y1, x2 - x1);
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle - Math.PI / 6), y2 - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - headlen * Math.cos(angle + Math.PI / 6), y2 - headlen * Math.sin(angle + Math.PI / 6));
        }

        // 1. Draw Central Axis
        ctx.save();
        ctx.lineWidth = thinLineWidth;
        ctx.beginPath();
        ctx.moveTo(x_left_center - 40, yc);
        ctx.lineTo(x_p + 40, yc);
        ctx.stroke();

        // Dash-dot pattern inside the cylinder
        ctx.beginPath();
        ctx.setLineDash([15, 5, 5, 5]); // dash-space-dot-space
        ctx.moveTo(x_left_center, yc);
        ctx.lineTo(x_right_center, yc);
        ctx.stroke();
        ctx.restore();

        // 2. Draw Cylinder
        ctx.lineWidth = baseLineWidth;
        
        // Top and bottom lines
        ctx.beginPath();
        ctx.moveTo(x_left_center, yc - R);
        ctx.lineTo(x_right_center, yc - R);
        ctx.moveTo(x_left_center, yc + R);
        ctx.lineTo(x_right_center, yc + R);
        ctx.stroke();

        // Right end (solid ellipse)
        ctx.beginPath();
        ctx.ellipse(x_right_center, yc, ellipseRx, R, 0, 0, 2 * Math.PI);
        ctx.stroke();

        // Left end (partially dashed)
        ctx.save();
        ctx.beginPath();
        ctx.setLineDash([6, 5]);
        ctx.ellipse(x_left_center, yc, ellipseRx, R, 0, Math.PI / 2, 3 * Math.PI / 2);
        ctx.stroke();
        ctx.restore(); 

        ctx.beginPath();
        ctx.ellipse(x_left_center, yc, ellipseRx, R, 0, -Math.PI / 2, Math.PI / 2);
        ctx.stroke();
        
        // 3. Draw Radius 'R'
        ctx.lineWidth = thinLineWidth + 0.5;
        ctx.beginPath();
        ctx.moveTo(x_right_center, yc);
        const R_angle = -Math.PI / 4;
        const R_end_x = x_right_center + ellipseRx * Math.cos(R_angle);
        const R_end_y = yc + R * Math.sin(R_angle);
        ctx.lineTo(R_end_x, R_end_y);
        ctx.stroke();

        ctx.font = mainFont;
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        ctx.fillText('R', x_right_center + 5, yc - 20);

        // 4. Draw Point P
        ctx.beginPath();
        ctx.arc(x_p, yc, 3, 0, 2 * Math.PI);
        ctx.fill();
        ctx.font = mainFont;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.fillText('P', x_p, yc - 8);
        
        // 5. Draw Dimension Lines 'l' and 'd'
        const y_dim_line = yc + R + 50;
        const tick_h = 15;
        
        ctx.save();
        ctx.lineWidth = thinLineWidth;

        // Ticks
        ctx.beginPath();
        ctx.moveTo(x_left_center, y_dim_line - tick_h/2);
        ctx.lineTo(x_left_center, y_dim_line + tick_h/2);
        ctx.moveTo(x_right_center, y_dim_line - tick_h/2);
        ctx.lineTo(x_right_center, y_dim_line + tick_h/2);
        ctx.moveTo(x_p, y_dim_line - tick_h/2);
        ctx.lineTo(x_p, y_dim_line + tick_h/2);
        ctx.stroke();
        
        // Arrow lines
        ctx.beginPath();
        // Line for 'l'
        ctx.moveTo(x_right_center, y_dim_line);
        ctx.lineTo(x_left_center, y_dim_line);
        drawArrow(x_right_center, y_dim_line, x_left_center, y_dim_line);
        drawArrow(x_left_center, y_dim_line, x_right_center, y_dim_line);
        
        // Line for 'd'
        ctx.moveTo(x_p, y_dim_line);
        ctx.lineTo(x_right_center, y_dim_line);
        drawArrow(x_p, y_dim_line, x_right_center, y_dim_line);
        drawArrow(x_right_center, y_dim_line, x_p, y_dim_line);
        ctx.stroke();
        
        // Labels
        ctx.font = mainFont;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.fillText('l', (x_left_center + x_right_center)/2, y_dim_line - 8);
        ctx.fillText('d', (x_right_center + x_p)/2, y_dim_line - 8);
        ctx.restore();
        
        // 6. Draw Caption
        const y_caption = y_dim_line + 50;
        ctx.font = captionFont;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('习题 7-11 图', (x_left_center + x_right_center)/2, y_caption);

    </script>
</body>
</html>